﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using SimpleExpression;
using System.Collections.ObjectModel;
using System.Collections;

namespace SimpleExpression
{
    public abstract class SelectCommandStrategy : ISelectCommandStrategy
    {
        protected object command;

        protected StringBuilder distinctClause;
        protected StringBuilder selectClause;
        protected StringBuilder fromClause;
        protected StringBuilder joinClause;
        protected StringBuilder whereClause;
        protected StringBuilder groupByClause;
        protected StringBuilder orderByClause;
        protected StringBuilder pagingClause;

        protected ICollection<string> attributesAliases;
        protected IDatabaseProvider provider;

        public const string SPACE = " ";

        public SelectCommandStrategy(IDatabaseProvider provider)
        {
            this.provider = provider;
            this.command = null;
            this.distinctClause = new StringBuilder();
            this.selectClause = new StringBuilder();
            this.fromClause = new StringBuilder();
            this.joinClause = new StringBuilder();
            this.whereClause = new StringBuilder();
            this.groupByClause = new StringBuilder();
            this.orderByClause = new StringBuilder();
            this.pagingClause = new StringBuilder();

            this.attributesAliases = new Collection<string>();
        }

        protected string Encode(object value)
        {
            return this.provider.Encode(value);
        }
        
        public abstract void AddAttribute(AttributeExpression expression);

        public abstract void AddCondition(ConditionExpression expression);

        public abstract void AddLinkEntity(LinkEntityExpression expression);

        public abstract void AddDistinctClause(EntityExpression expression);

        public abstract void AddFromClause(EntityExpression expression);

        public abstract void AddWhereClause(FilterExpression expression);

        public abstract void BeginFilterExpression(FilterExpression expression);

        public abstract void EndFilterExpression(FilterExpression expression);

        public abstract void AddGroupByClause(GroupByExpression expression);

        public abstract void AddOrderClause(OrderExpression expression);

        public abstract void AddPagingClause(PagingExpression expression);

        public virtual object Command 
        { 
            get { return this.command; } 
        }

        protected abstract string GetCommandText();

        public abstract void WriteCommand();
    }
}
